﻿using IsmsExplorer.Model.Iso27001;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using IsmsExplorer.Infrastructure;
using IsmsExplorer.Infrastructure.RepositoryFramework;

namespace IsmsExplorer.UnitTests {
    /// <summary>
    ///This is a test class for IIso27001ControlRepositoryTest and is intended
    ///to contain all IIso27001ControlRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class IIso27001ControlRepositoryTest {
        private TestContext testContextInstance;        
        private IIso27001ControlRepository _repository;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //

        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize() {            
            _repository = RepositoryFactory.GetRepository<IIso27001ControlRepository, Iso27001ControlBase>();
        }
        
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup() {
            _repository = null;            
        }
        
        #endregion

        internal virtual IIso27001ControlRepository CreateIIso27001ControlRepository() {
            // TODO: Instantiate an appropriate concrete class.
            IIso27001ControlRepository target = null;
            return target;
        }

        /// <summary>
        ///A test for FindAllSections
        ///</summary>
        [TestMethod()]
        public void FindAllSectionsTest() {
            IList<Iso27001ControlSection> sections = _repository.FindAllSections(recursive: false);
            // Currently there are 11 sections and that's the number expected from the database
            Assert.AreEqual(11, sections.Count);            
        }

        /// <summary>
        /// Tests the recursive abilities of the FindAll() method and indirectly the FindAllSubsections/Controls
        /// as they are called by FindAll() to retrieve all the children (subsections and controls).
        /// </summary>
        [TestMethod()]
        public void FindAllRecursiveTest() {
            IList<Iso27001ControlSection> sections = _repository.FindAllSections(recursive: true);
            Assert.AreEqual(11, sections.Count);
            int subsectionCount = 0;
            int controlCount = 0;
            foreach (var section in sections) {
                Assert.IsNotNull(section.Subsections);
                subsectionCount += section.Subsections.Count;
                foreach (var subsection in section.Subsections) {
                    Assert.IsNotNull(subsection.Controls);
                    controlCount += subsection.Controls.Count;
                }
            }
            Assert.AreEqual(39, subsectionCount);
            Assert.AreEqual(133, controlCount);
        }

        /// <summary>
        ///A test for FindAllControls
        ///</summary>
        [TestMethod()]
        public void FindAllControlsTest() {
            IList<Iso27001Control> controls = _repository.FindAllControls(subsection: null);
            Assert.AreEqual(133, controls.Count);
            // Get for a specific subsection.
            // We're expecting 7 controls for subsection ID 24 (we check that by looking at the SQL database or the standard).
            Iso27001ControlSubsection subsection = new Iso27001ControlSubsection(24, "", "", "");
            controls = _repository.FindAllControls(subsection);
            Assert.AreEqual(7, controls.Count);
        }

        /// <summary>
        ///A test for FindAllSubsections
        ///</summary>
        [TestMethod()]
        public void FindAllSubsectionsTest() {
            IList<Iso27001ControlSubsection> subsections = _repository.FindAllSubsections(section: null, recursive: false);
            Assert.AreEqual(39, subsections.Count);
            // Get for a specific section.
            // e.g. section ID 8 has 6 subsections
            Iso27001ControlSection section = new Iso27001ControlSection(8, "", "");
            subsections = _repository.FindAllSubsections(section, false);
            Assert.AreEqual(6, subsections.Count);
        }
    }
}
